package com.damai.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.citywithincity.db.interfaces.IValueConvert;
import com.damai.utils.value.ValueConvertFactory;

public class Caster {

	private static final Map<String, IValueConvert> convertMap;
	static {
		convertMap = new ConcurrentHashMap<String, IValueConvert>();
		
		append(String.class, Integer.class);
		append(String.class, Long.class);
		append(String.class, Short.class);
		append(String.class, Byte.class);
		append(String.class, Double.class);
		append(String.class, Float.class);
		
		append(String.class, int.class);
		append(String.class, long.class);
		/*
		append(String.class, short.class);
		append(String.class, byte.class);
		append(String.class, double.class);
		append(String.class, float.class);
		*/
		
		append(Number.class, String.class);
		append(Number.class, Integer.class);
		append(Number.class, Long.class);
		append(Number.class, Short.class);
		append(Number.class, Byte.class);
		append(Number.class, Double.class);
		append(Number.class, Float.class);
		
		
	}
	
	public IValueConvert getConvert(Class<?> src,Class<?> to){
		return convertMap.get(getKey(src, to));
	}
	
	
	private static final void append(Class<?> src,Class<?> to){
		try {
			convertMap.put(getKey(src, to), ValueConvertFactory.create(src,to));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static final String getKey(Class<?> srcClass,Class<?> toType) {
		String key = new StringBuilder(50).append(srcClass.getName()).append("2").append(toType.getName()).toString();
		if (key.length() > 50) {
			LogUtil.log("key " + key + " is long > 50");
		}
		return key;
	}

	/**
	 * 转成对应的类型
	 * 
	 * @param value
	 * @param type
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T to(Object value, Class<?> toType) {
		
		return (T) com.jzoom.caster.Caster.to(value, toType);
		
		/*if(toType==null){
			throw new RuntimeException("Totype must not be null!");
		}
		if (value == null) {
			if (toType.isPrimitive()) {
				if (toType == int.class)
					return (T) Integer.valueOf(0);
				else if (toType == long.class)
					return (T) Long.valueOf(0L);
				else if (toType == byte.class)
					return (T) Byte.valueOf((byte) 0);
				else if (toType == short.class)
					return (T) Short.valueOf((short) 0);
				else if (toType == float.class)
					return (T) Float.valueOf(.0f);
				else if (toType == double.class)
					return (T) Double.valueOf(.0);
				else if (toType == boolean.class)
					return (T) Boolean.FALSE;
				else if (toType == char.class)
					return (T) Character.valueOf(' ');
			}
			return null;
		}
		Class<?> srcClass = value.getClass();
		if(srcClass==toType || toType.isAssignableFrom(srcClass)){
			return (T) value;
		}
		String key = getKey(srcClass, toType);
		IValueConvert convert = convertMap.get(key);
		if (convert == null) {
			Class<?>[] s = extract(srcClass);
			Class<?>[] t = extract(toType);
			ll:for (Class<?> ss : s) {
				for (Class<?> tt : t) {
					String newKey = getKey(ss, tt);
					convert = convertMap.get(newKey);
					if (convert != null) {
						// 将两个class保存一下
						convertMap.put(key, convert);
						break ll;
					}
				}
			}
		}

		if (convert == null) {
			throw new RuntimeException("Cannot cast " + srcClass + " to " + toType);
		}

		return (T) convert.convert(value);
		*/
	}

	/**
	 * 解压缩,可以转化成interface\所有超类（除了Object)
	 * 
	 * @param target
	 * @return
	 */
	private static Class<?>[] extract(Class<?> target) {
		List<Class<?>> list = null;
		if (target.getInterfaces() != null) {
			list = Arrays.asList(target.getInterfaces());
		} else {
			list = new ArrayList<Class<?>>();
		}
		while (target != Object.class) {
			list.add(target);
			target = target.getSuperclass();
		}

		return list.toArray(new Class<?>[list.size()]);
	}

}
